package cn.com.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.Getter;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

/**
 * 对象映射器utils
 *
 * @author LiuGuodong
 * @date 2024/01/26
 */
public class ObjectMapperUtils {

    @Getter
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        // 设置日期格式
        OBJECT_MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        // 忽略未知属性
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 禁用空值处理
        OBJECT_MAPPER.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

        // 添加自定义模块（如果需要）
        SimpleModule customModule = new SimpleModule();
        // 在此添加自定义的序列化器、反序列化器等
        OBJECT_MAPPER.registerModule(customModule);
    }


    /**
     * 将对象序列化为 JSON 字符串
     *
     * @param object 对象
     * @return {@link String}
     * @throws JsonProcessingException json处理异常
     */
    public static String writeValueAsString(Object object) throws JsonProcessingException {
        return OBJECT_MAPPER.writeValueAsString(object);
    }

    /**
     * 将 JSON 字符串反序列化为指定类型的对象
     *
     * @param json      json
     * @param valueType 值类型
     * @return {@link T}
     * @throws IOException IOException
     */
    public static <T> T readValue(String json, Class<T> valueType) {
        try {
            return OBJECT_MAPPER.readValue(json, valueType);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 将 JSON 字符串反序列化为 List
     *
     * @param json        json
     * @param elementType 元素类型
     * @return {@link List}<{@link T}>
     * @throws IOException IOException
     */
    public static <T> List<T> readListValue(String json, Class<T> elementType) {
        JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, elementType);
        try {
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T readValue(String content, TypeReference<T> valueTypeRef) {
        try {
            return OBJECT_MAPPER.readValue(content, valueTypeRef);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将 JSON 字符串反序列化为 Map
     *
     * @param json      json
     * @param keyType   密钥类型
     * @param valueType 值类型
     * @return {@link Map}<{@link K}, {@link V}>
     * @throws IOException IOException
     */
    public static <K, V> Map<K, V> readMapValue(String json, Class<K> keyType, Class<V> valueType) {
        JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructMapType(Map.class, keyType, valueType);
        try {
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }


}
